﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using TjZheng.Core.Process.Filter;
using TjZheng.Core.Process.Handle;
using TjZheng.Core.Process.Helper;
using TjZheng.Framework;
using TjZheng.Web.Helper;
using TjZheng.WeiXin.Business;
using TjZheng.WeiXin.DataEntity;
using TjZheng.Cache;

namespace TjZheng.WeiXin.SDK.Pay
{
    public class NotifyProcessHandle : ProcessHandle
    {
        public override void OnExecuting(ProcessExecutingContext filterContext)
        {
            ProcessHelper.CheckProcessFilterContext(filterContext);
            NotifyProcessContext objNotifyProcessContext = filterContext.ProcessContext as NotifyProcessContext;
            if (objNotifyProcessContext == null)
            {
                throw new WxPayException("缺少统一下单接口上下文NotifyProcessContext为空！");
            }
            objNotifyProcessContext.CheckIntputWxPayPackage();

            WxPayPackage objIntputWxPayPackage = objNotifyProcessContext.IntputWxPayPackage;
            string appId = Convert.ToString(objIntputWxPayPackage.GetValue("appid"));
            if (appId.IsNull())
            {
                throw new WxPayException("微信支付系统传过来的数据包缺少appId");
            }


            BizMerchantInfo objBizMerchantInfo = new BizMerchantInfo();
            MerchantInfo objMerchantInfo = objBizMerchantInfo.GetRecordCache("", TimeSpan.FromSeconds(30), "AppId=@AppId AND IsRelease=1", new { AppId = appId });
            objNotifyProcessContext.SetMerchantInfo(objMerchantInfo);
            objNotifyProcessContext.CheckMerchantInfo();

            WxPayPackage objOutPutWxPayPackage = null;
            InvokeResult objInvokeResult = null;

            if (!objIntputWxPayPackage.IsValueSet("transaction_id"))
            {
                //若transaction_id不存在，则立即返回结果给微信支付后台
                objOutPutWxPayPackage = new WxPayPackage();
                objOutPutWxPayPackage.SetValue("return_code", "FAIL");
                objOutPutWxPayPackage.SetValue("return_msg", "支付结果中微信订单号不存在");

                objInvokeResult=new InvokeResult();
                objInvokeResult.ResultCode = "transaction_idNotSet";
                objInvokeResult.ResultMessage = "微信支付系统传过来的数据包缺少transaction_id";
                objInvokeResult.Data = objOutPutWxPayPackage;
                filterContext.Result = objInvokeResult;
                return;
            }

            bool isOrderExist = this.IsOrderExist(objIntputWxPayPackage, objNotifyProcessContext.MerchantInfo);
            if (!isOrderExist)
            {
                objOutPutWxPayPackage = new WxPayPackage();
                objOutPutWxPayPackage.SetValue("return_code", "FAIL");
                objOutPutWxPayPackage.SetValue("return_msg", "订单查询失败");

                objInvokeResult = new InvokeResult();
                objInvokeResult.ResultCode = "WeiXinOrderNotExist";
                objInvokeResult.Data = objOutPutWxPayPackage;
                filterContext.Result = objInvokeResult;
                return;
            }

            //更新订单
            string out_trade_no = Convert.ToString(objIntputWxPayPackage.GetValue("out_trade_no"));
            BizOrderInfo objBizOrderInfo = new BizOrderInfo(objMerchantInfo.MChId);
            OrderInfo objOrderInfo = objBizOrderInfo.GetRecord("OutTradeNo=@OutTradeNo AND TradeStatus=0", new { OutTradeNo = out_trade_no });
            if (objOrderInfo == null)
            {
                objOutPutWxPayPackage = new WxPayPackage();
                objOutPutWxPayPackage.SetValue("return_code", "FAIL");
                objOutPutWxPayPackage.SetValue("return_msg", "订单查询失败");

                objInvokeResult = new InvokeResult();
                objInvokeResult.ResultCode = "MerchantOrderNotExist";
                objInvokeResult.Data = objOutPutWxPayPackage;
                filterContext.Result = objInvokeResult;
                return;
            }

            if (objOrderInfo.TradeStatus >= 1)
            {
                objOutPutWxPayPackage = new WxPayPackage();
                objOutPutWxPayPackage.SetValue("return_code", "FAIL");
                objOutPutWxPayPackage.SetValue("return_msg", "订单已支付");

                objInvokeResult = new InvokeResult();
                objInvokeResult.ResultCode = "MerchantOrderHasPay";
                objInvokeResult.Data = objOutPutWxPayPackage;
                filterContext.Result = objInvokeResult;
                return;
            }

            int result = objBizOrderInfo.Update("TradeStatus=1 TransactionId=@TransactionId", "OutTradeNo=@OutTradeNo AND TradeStatus=0", new { OutTradeNo = out_trade_no, TransactionId = objIntputWxPayPackage.GetValue("transaction_id") });
            if (result <= 0)
            {
                objOutPutWxPayPackage = new WxPayPackage();
                objOutPutWxPayPackage.SetValue("return_code", "FAIL");
                objOutPutWxPayPackage.SetValue("return_msg", "订单更新失败");

                objInvokeResult = new InvokeResult();
                objInvokeResult.ResultCode = "MerchantOrderUpdateFaild";
                objInvokeResult.Data = objOutPutWxPayPackage;
                filterContext.Result = objInvokeResult;
                return;
            }

            this.NotifyMerchant(objIntputWxPayPackage, objNotifyProcessContext.MerchantInfo);
        }

        public override InvokeResult Execute(ProcessContext objProcessContext)
        {
            WxPayPackage objOutPutWxPayPackage = new WxPayPackage();
            objOutPutWxPayPackage.SetValue("return_code", "SUCCESS");
            objOutPutWxPayPackage.SetValue("return_msg", "OK");

            InvokeResult objInvokeResult = new InvokeResult();
            objInvokeResult.Data = objOutPutWxPayPackage;
            return objInvokeResult;
        }

        /// <summary>
        /// 验证通过后异步通知商户的回调动作
        /// </summary>
        /// <param name="objIntputWxPayPackage"></param>
        /// <param name="objMerchantInfo"></param>
        public virtual void NotifyMerchant(WxPayPackage objIntputWxPayPackage, MerchantInfo objMerchantInfo)
        {
            if (objMerchantInfo.McNotifyUrl.IsNull())
            {
                return;
            }

            HttpWebRequest objHttpWebRequest = objMerchantInfo.McNotifyUrl.CreateHttpRequest();
            objHttpWebRequest.Timeout = 10000;
            objHttpWebRequest.Method = "POST";

            //设置POST的数据类型和长度
            objHttpWebRequest.ContentType = "text/xml";

            string xml = objIntputWxPayPackage.ConvertToXml();
            byte[] data = Encoding.UTF8.GetBytes(xml);
            objHttpWebRequest.ContentLength = data.Length;

            //往服务器写入数据
            var reqStream = objHttpWebRequest.GetRequestStream();
            reqStream.Write(data, 0, data.Length);
            reqStream.Close();

            objHttpWebRequest.GetResponseAsync();
        }

        /// <summary>
        /// 从微信支付系统查询订单
        /// </summary>
        /// <param name="objIntputWxPayPackage"></param>
        /// <param name="objMerchantInfo"></param>
        /// <returns></returns>
        public virtual bool IsOrderExist(WxPayPackage objIntputWxPayPackage, MerchantInfo objMerchantInfo)
        {
            if (objIntputWxPayPackage == null)
            {
                throw new ArgumentNullException("objIntputWxPayPackage");
            }
            if (objMerchantInfo == null)
            {
                throw new ArgumentNullException("objMerchantInfo");
            }

            WxPayPackage objWxPayPackage = new WxPayPackage();
            string transaction_id = Convert.ToString(objIntputWxPayPackage.GetValue("transaction_id"));
            objWxPayPackage.SetValue("transaction_id", transaction_id);
            //检测必填参数
            if (!objWxPayPackage.IsValueSet("out_trade_no") && !objWxPayPackage.IsValueSet("transaction_id"))
            {
                throw new WxPayException("订单查询接口中，out_trade_no、transaction_id至少填一个！");
            }

            objWxPayPackage.SetValue("appid", objMerchantInfo.AppId);//公众账号ID
            objWxPayPackage.SetValue("mch_id", objMerchantInfo.MChId);//商户号
            objWxPayPackage.SetValue("nonce_str", WxPayApi.GenerateNonceStr());//随机字符串
            objWxPayPackage.SetValue("sign", objIntputWxPayPackage.CreateSign(objMerchantInfo.MKey));//签名

            string url = "https://api.mch.weixin.qq.com/pay/orderquery";
            WxPayPackage objOutputWxPayPackage = url.CreateWxPayApiRequest(objWxPayPackage, objMerchantInfo);

            if (objMerchantInfo.ReportLevel == 2)
            {
                this.ReportCostTime(objOutputWxPayPackage);
            }

            if (Convert.ToString(objOutputWxPayPackage.GetValue("return_code")) == "SUCCESS")
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 测速上报
        /// </summary>
        /// <param name="objOutputPackageResult"></param>
        public virtual void ReportCostTime(WxPayPackage objOutputPackageResult)
        {

        }

        public override void OnException(ExceptionFilterContext filterContext)
        {
            if (filterContext.Exception is WxPayException)
            {
                WxPayException objWxPayException = filterContext.Exception as WxPayException;
                filterContext.Result = new InvokeResult
                {
                    ResultCode = "WxPayException",
                    ResultMessage = objWxPayException.Message
                };
                filterContext.ExceptionHandled = true;
            }
        }
    }
}
